<template>
  <view class="list-box">
    <slot />
    <view class="list-Loadmore" v-if="current === 1 && isLoading === 1">
      <!-- <Loadmore :loadingType="1" /> -->
      <Empty :text="emptyText" v-if="records.length == 0" />
    </view>
    <slot
      v-else-if="useSlotsCustomEmpty && isLoading != 1 && records.length == 0"
      name="customEmpty"
    />
    <Empty :text="emptyText" v-else-if="isLoading != 1 && records.length == 0" />
    <Loadmore
      v-else-if="isShowLoadmore && records.length > 0 && current >= 1"
      :loadingType="isLoading"
      :loadingText="['上拉加载更多', '正在努力加载', loadingDoneText]"
    />
    <ScrollTop :bottom="scrollTopBottom" />
  </view>
</template>

<script lang="ts" setup>
  import { defineComponent, inject, provide, ref, computed, useSlots, onUnmounted } from 'vue';

  import { onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app';

  import Empty from '@/components/Empty/Empty.vue';
  import { propTypes } from '@/utils/propTypes';
  import { type ActionType } from './useConList';
  import Loadmore from '@/components/Loadmore/loadmore.vue';
  import { type IResData } from '@/api/indexTypes';
  import { isArray } from '@/utils/is';
  import ScrollTop from '../ScrollTop/index.vue';

  const useSlotsCustomEmpty = !!useSlots().customEmpty;

  const _ = defineProps({
    modelValue: propTypes.array.def([]),
    parame: propTypes.object.def({}),
    isApi: propTypes.bool.def(true),
    isInitApi: propTypes.bool.def(true),
    loading: propTypes.number.def(10),
    emptyText: propTypes.string.def('暂无内容'),
    size: propTypes.number.def(10),
    isShowLoadmore: propTypes.bool.def(true),
    scrollTopBottom: propTypes.number,
    isPullDownRefres: propTypes.bool.def(true),
    loadingDoneText: propTypes.string.def('已经加载全部数据'),
  });

  defineComponent({ Empty, Loadmore });

  const emit = defineEmits(['register', 'update:modelValue']);

  // const tabIsShow = inject<any>('tabIsShow');
  let api = inject<any>('api');
  const current = ref<number>(_.parame.current || 1);
  const size = ref<number>(_.parame.size || _.size);
  const records = ref<any[]>([]);
  const loadingType = ref<number>(1);
  const isLoading = computed(() => (_.isApi ? loadingType.value : _.loading));

  function getList() {
    if (current.value !== 1 && loadingType.value === 2) return;
    loadingType.value = 1;

    return api({
      ..._.parame,
      current: current.value,
      size: size.value,
    }).then((res: IResData<any>) => {
      current.value = res.current;
      size.value = res.size;
      let list = isArray(res.records) ? res.records : [];
      loadingType.value = list.length < size.value ? 2 : 0;
      records.value = res.current === 1 ? list : records.value.concat(list);
      emit('update:modelValue', records.value);
      return res;
    });
  }

  let addData = () => {
    if (!_.isApi || records.value.length == 0) return;
    if (loadingType.value !== 0) return;
    current.value += 1;
    return getList();
  }

  function refresh() {
    if (!_.isApi) return;
    current.value = 1;
    return getList().then((res: any) => {
      uni.stopPullDownRefresh();
      return res;
    });
  }

  const children: any[] = [];
  function resize() {
    // #ifndef APP-VUE || H5 || MP-WEIXIN
    children.forEach((vm) => {
      vm.init();
    });
    // #endif
  }
  function closeAll() {
    children.forEach((vm) => {
      // #ifdef APP-VUE || H5 || MP-WEIXIN
      vm.is_show = 'none';
      // #endif
      // #ifndef APP-VUE || H5 || MP-WEIXIN
      vm.close();
      // #endif
    });
  }

  let openItem: any;
  function closeOther(vm: any) {
    if (openItem && openItem !== vm) {
      // #ifdef APP-VUE || H5 || MP-WEIXIN
      openItem.is_show = 'none';
      // #endif
      // #ifndef APP-VUE || H5 || MP-WEIXIN
      openItem.close();
      // #endif
    }
    openItem = vm;
  }

  provide('List', {
    children,
    resize,
    closeAll,
    closeOther,
  });

  function setApi(_api: any) {
    api = _api;
  }

  emit('register', {
    refresh,
    setApi,
    closeAll,
    addData,
  } as ActionType);

  function init() {
    _.isInitApi && _.isApi && records.value.length == 0 && getList();
  }

  onReachBottom(() => addData());
  if (_.isPullDownRefres) {
    onPullDownRefresh(() => {
      refresh();
    });
  }

  onUnmounted(() => {
    addData = () => {};
  });

  // if (tabIsShow) {
  //   watch(tabIsShow, (v) => {
  //     if (v) {
  //       init();
  //     }
  //   });
  //   if (tabIsShow.value === true) init();
  // } else init();
  init();
</script>

<style lang="scss" scoped>
  .list-box {
    position: relative;

    .list-Loadmore {
      position: absolute;
      top: 100rpx;
      left: 0;
      right: 0;
      z-index: 10;
    }
  }
</style>
